/**
 * 
 */
package cz.cvut.fit.bugtrac.controller;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.google.appengine.api.urlfetch.URLFetchServiceFactory;

import cz.cvut.fit.bugtrac.chart.ChartService;
import cz.cvut.fit.bugtrac.exception.BugTracException;
import cz.cvut.fit.bugtrac.gexf.GexfService;
import cz.cvut.fit.bugtrac.manager.MetadataManager;
import cz.cvut.fit.bugtrac.manager.SnapshotManager;
import cz.cvut.fit.bugtrac.publicmodel.dto.metadata.MetadataDTO;
import cz.cvut.fit.bugtrac.publicmodel.dto.snapshot.SnapshotsDTO;

/**
 * @author Jaroslav Crhonek
 * 
 *         Controller for rest web service
 * 
 */
@Controller
@RequestMapping(value = "/api/v1")
public class ApiV1Controller {

	// properties injected by spring
	private MetadataManager metadataManager;
	private ChartService chartService;
	private SnapshotManager snapshotManager;
	private GexfService gexfService;

	/**
	 * metadata endpoint
	 * 
	 * @return JAXB bean - metadata
	 */
	@RequestMapping(value = "/metadata", method = RequestMethod.GET, produces = "application/xml")
	public @ResponseBody
	MetadataDTO metadata() {
		return getMetadataManager().getMetadata();
	}

	/**
	 * gexf endpoint
	 * 
	 * @return JAXB bean - metadata
	 * @throws BugTracException
	 * @throws IOException
	 * @throws UnsupportedEncodingException
	 */
	@RequestMapping(value = "/gexf", method = RequestMethod.GET, produces = "application/xml")
	public @ResponseBody
	String gexf() throws BugTracException, UnsupportedEncodingException,
			IOException {
		return getGexfService().getGexfGraph();
	}

	/**
	 * image snapshots endpoint
	 * 
	 * @return chart in form of image/png
	 * @throws IOException
	 * @throws MalformedURLException
	 * @throws URISyntaxException
	 * @throws BugTracException
	 */
	@RequestMapping(value = "/snapshots", method = RequestMethod.GET, produces = "image/png", headers = "Accept=image/png")
	public @ResponseBody
	byte[] snapshots_image() throws MalformedURLException, IOException,
			URISyntaxException, BugTracException {
		byte[] b = URLFetchServiceFactory.getURLFetchService()
				.fetch(getChartService().getChartUrl()).getContent();
		return b;
	}

	/**
	 * image snapshots endpoint
	 * 
	 * @return chart in form of image/png
	 * @throws IOException
	 * @throws MalformedURLException
	 * @throws URISyntaxException
	 * @throws BugTracException
	 */
	@RequestMapping(value = "/snapshots_image", method = RequestMethod.GET, produces = "image/png")
	public @ResponseBody
	byte[] snapshots_image_direct() throws MalformedURLException, IOException,
			URISyntaxException, BugTracException {
		return snapshots_image();
	}

	/**
	 * xml snapshots endpoint
	 * 
	 * @return chart in form of image/png
	 * @throws IOException
	 * @throws MalformedURLException
	 * @throws URISyntaxException
	 * @throws BugTracException
	 */
	@RequestMapping(value = "/snapshots", method = RequestMethod.GET, produces = "application/xml", headers = "Accept=application/xml")
	public @ResponseBody
	SnapshotsDTO snapshots_xml() throws MalformedURLException, IOException,
			URISyntaxException, BugTracException {
		return getSnapshotManager().getSnapshots();
	}

	/**
	 * @return the metadataManager
	 */
	public MetadataManager getMetadataManager() {
		return metadataManager;
	}

	/**
	 * @param metadataManager
	 *            the metadataManager to set
	 */
	@Autowired
	public void setMetadataManager(MetadataManager metadataManager) {
		this.metadataManager = metadataManager;
	}

	/**
	 * @return the chartService
	 */
	public ChartService getChartService() {
		return chartService;
	}

	/**
	 * @param chartService
	 *            the chartService to set
	 */
	@Autowired
	public void setChartService(ChartService chartService) {
		this.chartService = chartService;
	}

	/**
	 * @return the snapshotManager
	 */
	public SnapshotManager getSnapshotManager() {
		return snapshotManager;
	}

	/**
	 * @param snapshotManager
	 *            the snapshotManager to set
	 */
	@Autowired
	public void setSnapshotManager(SnapshotManager snapshotManager) {
		this.snapshotManager = snapshotManager;
	}

	/**
	 * @return the gexfService
	 */
	public GexfService getGexfService() {
		return gexfService;
	}

	/**
	 * @param gexfService
	 *            the gexfService to set
	 */
	@Autowired
	public void setGexfService(GexfService gexfService) {
		this.gexfService = gexfService;
	}

}
